package com.ocom.nettyxf.util;

/**
 * @Description: TODO
 * @Author: 朱晖
 * @Date: 2022/10/31
 **/

import cn.hutool.core.codec.Base64;
import com.ocom.common.utils.NumConvertUtil;
import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.asn1.*;

import java.math.BigInteger;
import java.nio.charset.StandardCharsets;

/**
 * @description: SM2签名 ASN1格式
 * @class: SM2SignAsn1
 * @author: yang37
 * @date: 2022/2/8 9:47
 * @version: 1.0
 */
@Slf4j
public class SM2SignAsn1 extends ASN1Object {
	private ASN1Integer int1;
	private ASN1Integer int2;

	public ASN1Integer getInt1() {
		return int1;
	}

	public void setInt1(ASN1Integer int1) {
		this.int1 = int1;
	}

	public ASN1Integer getInt2() {
		return int2;
	}

	public void setInt2(ASN1Integer int2) {
		this.int2 = int2;
	}

	public SM2SignAsn1(ASN1Integer int1, ASN1Integer int2) {
		this.int1 = int1;
		this.int2 = int2;
	}

	@Override
	public ASN1Primitive toASN1Primitive() {
		ASN1EncodableVector vector = new ASN1EncodableVector();
		vector.add(int1);
		vector.add(int2);
		return new DERSequence(vector);
	}


	/**
	 * 构建ASN1对象
	 */
	public static String buildSm2SignAsn1Object(BigInteger int1, BigInteger int2) {
		String res = null;
		try {

			SM2SignAsn1 sm2SignAsn1 = new SM2SignAsn1(
					new ASN1Integer(int1),
					new ASN1Integer(int2)
			);
			byte[] encoded = sm2SignAsn1.getEncoded();
			res = NumConvertUtil.bytesToHexString(encoded);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return res;
	}

	public static String parseSm2SignAsn1Object(String asn1Base64) {
		StringBuilder sb = new StringBuilder();
		byte[] data = NumConvertUtil.hexStringToByte(asn1Base64);
		ASN1InputStream ais = new ASN1InputStream(data);
		ASN1Primitive primitive;
		try {
			while ((primitive = ais.readObject()) != null) {
				// 原数据
				log.info("解析到sequence:\n{}", primitive);
				if (primitive instanceof ASN1Sequence) {
					ASN1Sequence sequence = (ASN1Sequence) primitive;
					ASN1SequenceParser parser = sequence.parser();
					ASN1Encodable encodable;
					while ((encodable = parser.readObject()) != null) {
						primitive = encodable.toASN1Primitive();
						String temp = String.valueOf(primitive);
						String s = new BigInteger(temp).toString(16);
//						String s = String.format("%064x",new BigInteger(temp));
						log.info("结果数据: {}", s);
						sb.append(s);
					}
				}
			}
			return sb.toString().replace("#", "");
		} catch (Exception e) {
			log.error("解析ASN1格式的SM2签名失败!", e);
			return "";
		}
	}

	public static String hexToBase64(String s) {
		return Base64.encode(s.getBytes(StandardCharsets.UTF_8));
	}

	public static void main(String[] args) throws Exception {
		// hex构建
//		BigInteger bigInteger1 = new BigInteger("EC0E1276175276F2F82046DFB26D06125E1B3F23981AF78C14F6DCDE4ADB19C4", 16);
//		BigInteger bigInteger2 = new BigInteger("10589A985509C217E9B691F258B9FAB074DBDEE60AACDF4052950D499619E33E", 16);
		// hex构建
		BigInteger bigInteger1 = new BigInteger("4BECFA44FE4C9819F784B7DF7216288A6DB33F947C10B3413BAF3A12330F99DB", 16);
		BigInteger bigInteger2 = new BigInteger("EAC5FC31FD67D30224FF8F8918B00936F5392E1BB6C3653C69272A7111AF5B70", 16);

		String sm2SignAsn1 = SM2SignAsn1.buildSm2SignAsn1Object(bigInteger1, bigInteger2);
		System.out.printf("ASN1格式: %s",sm2SignAsn1);
		System.out.println();
		System.out.printf("长度: %d",sm2SignAsn1.length());

		SM2SignAsn1.parseSm2SignAsn1Object(sm2SignAsn1);

		SM2SignAsn1.parseSm2SignAsn1Object("3044022039607f2f4bb4312c9e0f672901f81f8f43c6c0388e199fa77ebae22ffe6779c902205db043c8cb9a8788de73ad9c6ecb6884bb1908d92e3ecaea39532590d83de4e0");


	}

}

